zoo -command archive [file] ...
This documentation is for version 2.1. Changes from previous versions are described in the section labelled CHANGES.
The command zoo h gives a summary of commands. Extended multiscreen help can be obtained with zoo H.
Zoo will not add an archive to itself, nor add the archive's backup (with .bak extension to the filename) to the archive.
Zoo has two types of commands: Expert commands, which consist of one command letter followed by zero or more modifier characters, and Novice commands, which consist of a hyphen (`-') followed by a command word that may be abbreviated. Expert commands are case-sensitive but Novice commands are not.
When zoo adds a file to an existing archive, the default action is to maintain one generation of each file in an archive and to mark any older generation as deleted. A limit on the number of generations to save can be specified by the user for an entire archive, or for each file individually, or both. Zoo deletes a stored copy of an added file if necessary to prevent the number of stored generations from exceeding the user-specified limit.
Deleted files may be later undeleted. Archives may be packed to recover space occupied by deleted files.
All commands assume that the archive name ends with the characters .zoo unless a different extension is supplied.
Novice commands
Novice commands may be abbreviated to a hyphen followed by at least one command character. Each Novice command works in two stages. First, the command does its intended work. Then, if the result was that one or more files were deleted in the specified archive, the archive is packed. If packing occurs, the original unpacked archive is always left behind with an extension of .bak.
No Novice command ever stores the directory prefix of a file.
The Novice commands are as follows.
The correspondence between Novice and Expert commands is as follows.
Novice | Equivalent | |
Command | Description | Expert Command |
-add | add files to archive | aP: |
-extract | extract files from archive | x |
-move | move files to archive | aMP: |
-test | test archive integrity | xNd |
extract files to standard output | xp | |
-delete | delete files from archive | DP |
-list | list archive contents | VC |
-update | add new or newer files | aunP: |
-freshen | by add newer files | auP: |
-comment | add comments to files | c |
Expert commands
The general format of expert commands is:
zoo {acfDeghHlLPTuUvVx}[aAcCdEfghImMnNoOpPqSu1:/.@n+-=] archive [file] ...
The characters enclosed within {} are commands. Choose any one of these. The characters enclosed within [] just to the right of the {} are modifiers and zero or more of these may immediately follow the command character. All combinations of command and modifier characters may not be valid.
Files are added to an archive with the command:
zoo {au}[cfhIMnPqu:+-] archive [file] ...
Command characters are:
The following modifiers are specific to these commands.
The combination of the n modifier with the u modifier or u command causes addition of a file to the archive either if the file is not already in the archive, or if the file is already in the archive but the archived copy is older than the copy being added.
Under the **IX family of operating systems, zoo can be used as follows in a pipeline:
If the I modifier is specified, no filenames may be supplied on the command line itself.
Files are extracted from an archive with the command:
zoo {ex}[dNoOpqS./@] archive [file] ...
The e and x commands are synonymous. If no file was specified, all files are extracted from the archive.
The following modifiers are specific to the e and x commands:
On **IX systems, however, doubling this modifier as OO will force zoo to unconditionally overwrite any read-protected files with extracted files if it can do so.
The O, N, and p modifiers are mutually exclusive.
The management of multiple generations of archived files is done with the commands:
zoo gl[Aq]{+-=}number archive files ..
zoo gc[q]{+-=}number archive files ..
zoo gA[q]- archive
zoo gA[q]+ archive
The first form, gl, adjusts the generation limit of selected files by the specified value. If the form =n is used, where n is a decimal number, this sets the generation limit to the specified value. If + or - are used in placed of = the effect is to increment or decrement the generation limit by the specified value. For example, the command
If the A modifier is used, the archive-wide generation limit is adjusted instead.
The number of generations of a file maintained in an archive is limited by the file generation limit, or the archive generation limit, whichever is lower. As a special case, a generation limit of 0 stands for no limit. Thus the default file generation limit of 0 and archive generation limit of 3 limits the number of generations of each file in a newly-created archive to three.
The generation limit specified should be in the range 0 through 15; any higher numbers are interpreted modulo 16.
The second form of the command, using gc, adjusts the generation count of selected files. Each file has a generation count of 1 when it is first added to an archive. Each time a file by the same name is added again to an archive, it receives a generation count that is one higher than the highest generation count of the archived copy of the file. The permissible range of generation counts is 1 through 65535. If repeated manipulations of an archive result in files having very high generation counts, they may be set back to lower numbers with the gc command. The syntax of the command is analogous to the syntax of the gl command, except that the A modifier is not applicable to the gc command.
The third form, gA-, disables generations in an archive. Generations are off when an archive is first created, but may be enabled with the fourth form of the command, gA+. When generations are disabled in an archive, zoo will not display generation numbers in archive listings or maintain multiple generations. Generations can be re-enabled at any time, though manipulation of an archive with repeated interspersed gA- and gA+ commands may result in an archive whose behavior is not easily understandable.
Archived files are listed with the command:
zoo {lLvV}[aAcCdfgmqvV@/1+-] archive[.zoo] [file] ...
If no filename is supplied all files are listed except deleted files.
Zoo selects which generation(s) of a file to list according to the following algorithm.
If no filename is supplied, only the latest generation of each file is listed. If any filenames are specified, and a generation is specified for an argument, only the requested generation is listed. If a filename is specified ending with the generation character (`:' or `;'), all generations of that file are listed. Thus a filename argument of the form zoo.c will cause only the latest generation of zoo.c to be listed; an argument of the form zoo.c:4 will cause generation 4 of zoo.c to be listed; and an argument of the form zoo.c: or zoo.c:* will cause all generations of zoo.c to be listed.
On **IX systems, on which the shell expands arguments, if multiple archives are to be listed, the L command must be used. On other systems (VAX/VMS, AmigaDOS, MSDOS) on which wildcard expansion is done internally by zoo, wildcards may be used in the archive name, and a multiple archive listing obtained, using the l command.
Both the V and v command characters can also be used as modifiers to the l and L commands.
In addition to the general modifiers described later, the following modifiers can be applied to the archive list commands.
In addition to the generation information for each file, the archive-wide generation limit, if any, is shown at the end of the listing. If generations have been disabled by the user, this is so indicated, for example:
Files may be deleted and undeleted from an archive with the following commands:
zoo {DU}[Pq1] archive file ...
The D command deletes the specified files and the U command undeletes the specified files. The 1 modifier (the digit one, not the letter ell) forces deletion or undeletion of at most one file. If multiple instances of the same file exist in an archive, use of the 1 modifier may allow selective extraction of one of these.
Comments may be added to an archive with the command:
zoo c[A] archive
Without the modifier A, this behaves identically to the -comment command. With the modifier A, the command serves to add or update the comment attached to the archive as a whole. This comment may be listed with the lA, LA, v, and V commands. Applying the cA command to an archive that was created with an older version of zoo will result in an error message requesting that the user first pack the archive with the P command. This reorganizes the archive and creates space for the archive comment.
The timestamp of an archive may be adjusted with the command:
zoo T[q] archive
Zoo normally attempts to maintain the timestamp of an archive to reflect the age of the newest file stored in it. Should the timestamp ever be incorrect it can be fixed with the T command.
An archive may be packed with the command:
zoo P[EPq] archive
If the backup copy of the archive already exists, zoo will refuse to pack the archive unless the P modifier is also given. The E modifier causes zoo not to save a backup copy of the original archive after packing. A unique temporary file in the current directory is used to initially hold the packed archive. This file will be left behind if packing is interrupted or if for some reason this file cannot be renamed to the name of the original archive when packing is complete.
Packing removes any garbage data appended to an archive because of Xmodem file transfer and also recovers any wasted space remaining in an archive that has been frequently updated or in which comments were replaced. Packing also updates the format of any archive that was created by an older version of zoo so that newer features (e.g. archive-wide generation limit, archive comment) become fully available.
Zoo can act as a pure compression or uncompression filter, reading from standard input and writing to standard output. This is achieved with the command:
zoo f{cu}[h]
where c specifies compression, u specifies uncompression, and h used in addition requests the high-performance compression be used. A CRC value is used to check the integrity of the data. The compressed data stream has no internal archive structure and contains multiple files only if the input data stream was already structured, as might be obtained, for example, from tar or cpio.
Modem transfers can be speeded up with these commands:
General modifiers
The following modifiers are applicable to several commands:
When doubled as qq, this modifier suppresses WARNING messages, and when tripled as qqq, ERROR messages are suppressed too. FATAL error messages are never suppressed.
Recovering data from damaged archives
The @ modifier allows the user to specify the exact position in an archive where zoo should extract a file from, allowing damaged portions of an archive to be skipped. This modifier must be immediately followed by a decimal integer without intervening spaces, and possibly by a comma and another decimal integer, giving a command of the form l@m or l@m,n (to list archive contents) or x@m or x@m,n (to extract files from an archive). Listing or extraction begin at position m in the archive. The value of m must be the position within the archive of an undamaged directory entry. This position is usually obtained from fiz(1) version 2.0 or later.
If damage to the archive has shortened or lengthened it, all positions within the archive may be changed by some constant amount. To compensate for this, the value of n may be specified. This value is also usually obtained from fiz(1). It should be the position in the archive of the file data corresponding to the directory entry that has been specified with m. Thus if the command x@456,575 is given, it will cause the first 456 bytes of the archive to be skipped and extraction to begin at offset 456; in addition, zoo will attempt to extract the file data from position 575 in the archive instead of the value that is found in the directory entry read from the archive. For example, here is some of the output of fiz when it acts on a damaged zoo archive:
**************** 2526: DIR [changes] ==> 95 2587: DATA **************** 3909: DIR [copyrite] ==> 1478 3970: DATA 4769: DATA ****************
In such output, DIR indicates where fiz found a directory entry in the archive, and DATA indicates where fiz found file data in the archive. Filenames located by fiz are enclosed in square brackets, and the notation "==> 95" indicates that the directory entry found by fiz at position 2526 has a file data pointer to position 95. (This is clearly wrong, since file data always occur in an archive after their directory entry.) In actuality, fiz found file data at positions 2587, 3970, and 4769. Since fiz found only two directory entries, and each directory entry corresponds to one file, one of the file data positions is an artifact.
In this case, commands to try giving to zoo might be x@2526,2587 (extract beginning at position 2526, and get file data from position 2587), x@3090,3970 (extract at 3090, get data from 3970) and x@3909,4769 (extract at 3909, get data from 4769). Once a correctly-matched directory entry/file data pair is found, zoo will in most cases synchronize with and correctly extract all files subsequently found in the archive. Trial and error should allow all undamaged files to be extracted. Also note that self-extracting archives created using sez (the Self-Extracting Zoo utility for MS-DOS), which are normally executed on an MS-DOS system for extraction, can be extracted on non-MSDOS systems using zoo's damaged-archive recovery method using the @ modifier.
Wildcard handling
Under the **IX family of operating systems, the shell normally expands wildcards to a list of matching files. Wildcards that are meant to match files within an archive must therefore be escaped or quoted. When selecting files to be added to an archive, wildcard conventions are as defined for the shell. When selecting files from within an archive, wildcard handling is done by zoo as described below.
Under MS-DOS and AmigaDOS, quoting of wildcards is not needed. All wildcard expansion of filenames is done by zoo, and wildcards inside directory names are expanded only when listing or extracting files but not when adding them.
The wildcard syntax interpreted by zoo is limited to the following characters.
Arbitrary combinations of * and ? are allowed.
MS-DOS users should note that zoo does not treat the dot as a special character, and it does not ignore characters following an asterisk. Thus * matches all filenames; *.* matches filenames containing a dot; *_* matches filenames containing an underscore; and *z matches all filenames that end with the character z, whether or not they contain a dot.
Usage hints
The Novice command set in zoo is meant to provide an interface with functionality and format that will be familiar to users of other similar archive utilities. In keeping with this objective, the Novice commands do not maintain or use any subdirectory information or allow the use of zoo's ability to maintain multiple generations of files. For this reason, users should switch to exclusively using the Expert commands as soon as possible.
Although the Expert command set is quite large, it should be noted that in almost every case, all legal modifiers for a command are fully orthogonal. This means that the user can select any combination of modifiers, and when they act together, they will have the intuitively obvious effect. Thus the user need only memorize what each modifier does, and then can combine them as needed without much further thought.
For example, consider the a command which is used to add files to an archive. By itself, it simply adds the specified files. To cause only already-archived files to be updated if their disk copies have been modified, it is only necessary to add the u modifier, making the command au. To cause only new files (i.e., files not already in the archive) to be added, the n modifier is used to create the command an. To cause both already-archived files to be updated and new files to be added, the u and n modifiers can be used together, giving the command aun. Since the order of modifiers is not significant, the command could also be anu.
Further, the c modifier can be used to cause zoo to prompt the user for a comment to attach to each file added. And the f modifier can cause fast addition (addition without compression). It should be obvious then that the command auncf will cause zoo to update already-archived files, add new files, prompt the user for comments, and do the addition of files without any compression. Furthermore, if the user wishes to move files to the archive, i.e., delete the disk copy of each file after it is added to the archive, it is only necessary to add the M modifier to the command, so it becomes auncfM. And if the user also wishes to cause the archive to be packed as part of the command, thus recovering space from any files that are replaced, the command can be modified to auncfMP by adding the P modifier that causes packing.
Similarly, the archive listing commands can be built up by combining modifiers. The basic command to list the contents of an archive is l. If the user wants a fast columnized listing, the f modifier can be added to give the lf command. Since this listing will have a header giving the archive name and a trailer summarizing interesting information about the archive, such as the number of deleted files, the user may wish to "quieten" the listing by suppressing these; the relevant modifier is q, which when added to the command gives lfq. If the user wishes to see the **IX mode (file protection) bits, and also information about multiple generations, the modifiers m (show mode bits) and g (show generation information) can be added, giving the command lfqmg. If the user also wishes to see an attached archive comment, the modifier A (for archive) will serve. Thus the command lfqmgA will give a fast columnized listing of the archive, suppressing any header and trailer, showing mode bits and generation information, and showing any comment attached to the archive as a whole. If in addition individual comments attached to files are also needed, simply append the c modifier to the command, making it lfqmgAc. The above command will not show any deleted files, however; to see them, use the d modifier, making the command lfqmgAcd (or double it as in lfqmgAcdd if only the deleted files are to be listed). And if the user also wishes to see the CRC value for each file being listed, the modifier C will do this, as in the command lfqmgAcdC, which gives a fast columnized listing of all files, including deleted files, showing any archive comment and file comments, and file protection codes and generation information, as well as the CRC value of each file.
Note that the above command lfqmgAcdC could also be abbreviated to VfqmgdC because the command V is shorthand for lcA (archive listing with all comments shown). Similarly the command v is shorthand for lA (archive listing with archive comment shown). Both V and v can be used as modifiers to any of the other archive listing commands.
Generations
By default, zoo assumes that only the latest generation of a specified file is needed. If generations other than the latest one need to be selected, this may be done by specifying them in the filename. For example, the name stdio.h would normally refer to the latest generation of the file stdio.h stored in a zoo archive. To get an archive listing showing all generations of stdio.h in the archive, the specification stdio.h:* could be used (enclosed in single quotes if necessary to protect the wildcard character * from the shell). Also, stdio.h:0 selects only the latest generation of stdio.h, while stdio.h:^0 selects all generations except the latest one. The : character here separates the filename from the generation number, and the character * is a wildcard that matches all possible generations. For convenience, the generation itself may be left out, so that the name stdio.h: (with the : but without a generation number or a wildcard) matches all generations exactly as stdio.h:* does.
If a generation is specified but no filename is present, as in :5, :*, or just :, all filenames of the specified generation will be selected. Thus :5 selects generation 5 of each file, and :* and : select all generations of all files.
It is important to note that zoo's idea of the latest generation of a file is not based upon searching the entire archive. Instead, whenever zoo adds a file to an archive, it is marked as being the latest generation. Thus, if the latest generation of a file is deleted, then no generation of that file is considered the latest any more. This can be surprising to the user. For example, if an archive already contains the file stdio.h:5 and a new copy is added, appearing in the archive listing as stdio.h:6, and then stdio.h:6 is deleted, the remaining copy stdio.h:5 will no longer be considered to be the latest generation, and the file stdio.h:5, even if undeleted, will no longer appear in an archive listing unless generation 5 (or every generation) is specifically requested. This behavior will likely be improved in future releases of zoo.
archive_name.bak - backup of archive
Files with generation counts that wrap around from 65535 to 1 are not currently handled correctly. If a file's generation count reaches a value close to 65535, it should be manually set back down to a low number. This may be easily done with a command such as gc-65000, which subtracts 65000 from the generation count of each specified file. This problem will be fixed in a future release.
Although zoo on **IX systems preserves the lowest nine mode bits of regular files, it does not currently do the same for directories.
Currently zoo's handling of the characters : and ; in filenames is not robust, because it interprets these to separate a filename from a generation number. A quoting mechanism will eventually be implemented.
Standard input cannot be archived nor can a created archive be sent to standard output. Spurious error messages may appear if the filename of an archive is too long.
Since zoo never archives any file with the same name as the archive or its backup (regardless of any path prefixes), care should be taken to make sure that a file to be archived does not coincidentally have the same name as the archive it is being added to. It usually suffices to make sure that no file being archived is itself a zoo archive. (Previous versions of zoo sometimes tried to add an archive to itself. This bug now seems to be fixed.)
Only regular files are archived; devices and empty directories are not. Support for archiving empty directories and for preserving directory attributes is planned for the near future.
Early versions of MS-DOS have a bug that prevents "." from referring to the root directory; this leads to anomalous results if the extraction of paths beginning with a dot is attempted.
VAX/VMS destroys case information unless arguments are enclosed in double quotes. For this reason if a command given to zoo on a VAX/VMS system includes any uppercase characters, it must be enclosed in double quotes. Under VAX/VMS, zoo does not currently restore file timestamps; this will be fixed as soon as I figure out RMS extended attribute blocks, or DEC supplies a utime() function, whichever occurs first. Other VMS bugs, related to file structures, can often be overcome by using the program bilf.c that is supplied with zoo.
It is not currently possible to create a zoo archive containing all zoo archives that do not contain themselves.
Thanks are due to the following people and many others too numerous to mention.
J. Brian Waters <jbwaters@bsu-cs.bsu.edu>, who has worked diligently to port zoo to AmigaDOS, created Amiga-specific code, and continues keeping it updated.
Paul Homchick <rutgers!cgh!paul>, who provided numerous detailed reports about some nasty bugs.
Bill Davidsen <davidsen@crdos1.crd.ge.com>, who provided numerous improvements to this manual, contributed multiscreen help, and provided many useful bug reports, bug fixes, code improvements, and suggestions.
Mark Alexander <amdahl!drivax!alexande>, who provided me with some bug fixes.
Haruhiko Okumura, who wrote the ar archiver and some excellent compression code, which I adapted for use in zoo.
Randal L. Barnes <rlb@skyler.mavd.honeywell.com>, who (with Randy Magnuson) wrote the code to support the preservation of file timestamps under VAX/VMS.
Raymond D. Gardner, who contributed replacement uncompression code that on some systems is twice as fast as the original.
Greg Yachuk and Andre Van Dalen, who independently modified MS-DOS zoo to support multivolume archives. (This support is not yet in this official release.)